<template>
  <div class="table_container">
    <el-table
      :height="height"
      :max-height="maxHeight"
      :stripe="stripe"
      :border="border"
      :show-header="showHeader"
      :size="size"
      :empty-text="emptyText"
      :highlight-current-row="highlightCurrentRow"
      :header-cell-class-name="headerCellClassName"
      :header-cell-style="headerCellStyle"
      :header-row-class-name="headerRowClassName"
      :header-row-style="headerRowStyle"
      :data="tableData"
      style="width: 100%"
      @select="select"
      @selection-change="selectionChange"
    >
      <template v-for="(column, index) in tableColumns" :key="index">
        <!-- 具名插槽 -->
        <el-table-column
          v-if="column.slot"
          :label="column.label"
          :show-overflow-tooltip="column.showOverflowTooltip"
          :width="column.width"
          :min-width="column.minWidth"
          :align="column.align"
        >
          <template #default="scope">
            <slot :name="column.slotName" :row="scope"></slot>
          </template>
        </el-table-column>
        <!-- 普通列 -->
        <el-table-column
          v-else-if="!column.slot"
          :type="column.type"
          :prop="column.prop"
          :label="column.label"
          :show-overflow-tooltip="column.showOverflowTooltip"
          :width="column.width"
          :min-width="column.minWidth"
          :align="column.align"
          :formatter="column.formatter"
          :selectable="column.selectable"
        />
      </template>
    </el-table>
    <!-- 分页 -->
    <PaginationComponent
      @page-change="onPageChange"
      @page-size-change="onPageSizeChange"
      :total="total"
      :current-page="currentPage"
      :page-size="pageSize"
      :pagination-align="paginationAlign"
    ></PaginationComponent>
  </div>
</template>

<script lang="ts" setup>
import type { TableColumns } from "types/components/table";
import { CSSProperties } from "vue";
import { ColumnCls, ColumnStyle } from "element-plus/es/components/table/src/table/defaults";
import type { TableColumnCtx } from "element-plus/es/components/table/src/table-column/defaults";
import PaginationComponent from "../pagination/PaginationComponent.vue";

interface props {
  /**
   * 表格高度
   */
  height?: string | number;
  /**
   * 表格最大高度
   */
  maxHeight?: string | number;
  /**
   * 是否为斑马纹表格，默认为false
   */
  stripe?: boolean;
  /**
   * 是否带有纵向边框，默认为false
   */
  border?: boolean;
  /**
   * 是否显示表头，默认为true
   */
  showHeader?: boolean;
  /**
   * 是否高亮当前行，默认为false
   */
  highlightCurrentRow?: boolean;
  /**
   * 表格尺寸
   */
  size?: "large" | "default" | "small";
  /**
   * 表格数据
   */
  tableData: any[];
  /**
   * 表格列数据对象，每列表格数据集合
   */
  tableColumns: TableColumns[];
  /**
   * 空数据时显示的文本内容 例如：暂无数据
   */
  emptyText?: string;

  /**
   * 表头行的 style 的回调方法，也可以使用一个固定的 Object
   * 例如：{background:'orange'}
   * 为所有表头行设置Style，但是需要注意，如果设置该属性后样式不生效，
   * 可能是被其他属性默认值给覆盖了
   */
  headerRowStyle?: ColumnStyle<any> | undefined;
  /**
   * 表头行的 className 的回调方法，也可以使用字符串为所有表头行设置一个固定的 className。
   */
  headerRowClassName?: ColumnCls<any> | undefined;
  /**
   * 表头单元格的 className 的回调方法，也可以使用字符串为所有表头单元格设置一个固定的 className。
   */
  headerCellClassName?:
    | string
    | ((data: {
        row: any;
        rowIndex: number;
        column: TableColumnCtx<any>;
        columnIndex: number;
      }) => string)
    | undefined;
  /**
   *表头单元格的 style 的回调方法，也可以使用一个固定的 Object 为所有表头单元格设置一样的 Style。
   */
  headerCellStyle?:
    | CSSProperties
    | ((data: {
        row: any;
        rowIndex: number;
        column: TableColumnCtx<any>;
        columnIndex: number;
      }) => CSSProperties)
    | undefined;

  /**
   * 总条数
   */
  total?: number;
  /**
   * 当前页码，默认当前第1页
   */
  currentPage?: number;
  /**
   * 分页每页条数，默认每页10条数据
   */
  pageSize?: number;
  /**
   * 分页组件的位置 默认值：'left'
   */
  paginationAlign?: "left" | "center" | "right";
}

withDefaults(defineProps<props>(), {
  stripe: false,
  border: false,
  size: "default",
  showHeader: true,
  highlightCurrentRow: false,
  total: 0,
  paginationAlign: "left",
});

// 事件分发
const emit = defineEmits(["pageChange", "pageSizeChange", "selectionChange", "select"]);
/**
 * 每页条数发生变化时触发
 * @param pageSize 每页条数
 */
function onPageChange(page: number) {
  emit("pageChange", page);
}
/**
 * 当前页码发生变化时触发
 * @param currentPage 当前多少页
 */
function onPageSizeChange(pageSize: number) {
  emit("pageSizeChange", pageSize);
}
/**
 * 复选框勾选事件
 * @param selectList 被勾选的复选框集合
 */
function selectionChange<T>(selectList: T[]) {
  emit("selectionChange", selectList);
}
/**
 * 当用户手动勾选数据行的 Checkbox 时触发的事件
 */
function select(selection: any[], row: any) {
  emit("select", selection, row);
}
</script>
